home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / qformat1.zip / ZAP.CPP < prev    next >
C/C++ Source or Header  |  1993-01-18  |  6KB  |  177 lines

  1. //      ZAP (quick format) disk
  2.  
  3. //      Bad cluster information is retained!
  4.  
  5. #include    <dos.h>
  6. #include    <string.h>
  7. #include    <stdlib.h>
  8. #include    <stdio.h>
  9. #include    <iostream.h>                 
  10. #include    <iomanip.h>
  11. #include    <ctype.h>
  12.  
  13. typedef    unsigned char   byte;
  14. typedef    unsigned int    WORD;
  15. typedef    unsigned long   dword;
  16.  
  17. const char NUL = '\0';
  18.  
  19. class dpb {
  20.   public:
  21.     byte    driveno;            // Drive number (0 == A:)
  22.     byte    unit;               // Unit number within driver
  23.     WORD    bpers;              // Bytes per sector
  24.     byte    hisect;             // Highest sector number in cluster
  25.     byte    shift;              // To convert clusters into sectors
  26.     WORD    reserved;           // Reserved sectors
  27.     byte    nfats;              // Number of FATs
  28.     WORD    ndir;               // Number of root directory entries
  29.     WORD    data;               // Number of first sector with user data
  30.     WORD    ndata;              // Highest cluster number + 1
  31.                                 //   16 bit FAT if > 0ff6
  32.     WORD    sperf;              // Sectors per FAT
  33.     WORD    sdir;               // Number of first directory sector
  34.     dpb     far *dhdr;          // Address of device driver header
  35.     byte    media;              // Media ID byte
  36.     byte    clean;              // 0 if disk accessedm else FF
  37.     dpb     far *next;          // Pointer to next DPB
  38.     WORD    search;             // Search start cluster, usually the last
  39.                                 //  allocated
  40.     WORD    nfree;              // Number of free clusters on drive or FFFFh
  41.  
  42.     WORD    infolevel;
  43.     WORD    Slo;                // Serial # (low order word)
  44.     WORD    Shi;                //          (high order word)
  45.     char    label[11];          // Volume label
  46.     char    ftype[8];           // File system type
  47.  
  48.     unsigned *FAT;              // Points to FAT buffer
  49.     char    is16bit;            // Set if 16 bit FAT
  50.  
  51.     dpb(char);                  // Constructor
  52.     void    list();             // List dpb to cout
  53.     void    erase();
  54.     unsigned sector(unsigned);
  55.     unsigned getentry(unsigned);
  56.     void     zapentry(unsigned);
  57. };
  58.  
  59. dpb::dpb(char drv)              // 0 == default drive!
  60. {
  61.     void far *result;           // Points to DOS copy of the dpb
  62. asm {
  63.     push ds
  64.     mov dl,drv
  65.     and dl,15
  66.     mov ah,0x32
  67.     int 0x21
  68.     xor al,al
  69.     je  okay
  70.     xor bx,bx
  71.     mov ds,bx
  72.     }
  73. okay:
  74. asm {
  75.     mov dx,ds
  76.     pop ds
  77.     }
  78.     result = MK_FP(_DX, _BX);
  79.     _fmemcpy((void *)this, result, 33);
  80.     _DX = (unsigned)&infolevel;
  81. asm {
  82.     mov bl,drv
  83.     and bl,15
  84.     mov ax,0x6900
  85.     int 0x21
  86.     }
  87.     is16bit = ftype[4] == '6';
  88.     ftype[5] = NUL;
  89. }
  90.  
  91. void dpb::list()
  92. {
  93.     char save = *ftype; *ftype = NUL;       // Temporary hack
  94.     cout.setf(ios::left);
  95.     cout << "\n\tDrive Parameter Block\n" <<
  96.         "\n\tDrive " << (char)('A' + driveno) <<
  97.         "\n\tBytes per sector                  " << bpers <<
  98.         "\n\tSectors per cluster               " << (hisect + 1) <<
  99.         "\n\tClusters to sectors shift         " << (int)shift <<
  100.         "\n\tReserved sectors                  " << reserved <<
  101.         "\n\tNumber of FATs                    " << (int)nfats <<
  102.         "\n\tNumber of root directory entries  " << ndir <<
  103.         "\n\tFirst user data sector            " << data <<
  104.         "\n\tNumber of data clusters           " << (ndata - 1);
  105.     if (nfree != 65535) {
  106. cout << "\n\tNumber of free clusters           " << nfree ;}
  107. cout << "\n\tSearch start cluster              " << search <<
  108.         "\n\tSectors per FAT                   " << sperf <<
  109.         "\n\tFirst directory sector            " << sdir <<
  110.         "\n\tMedia ID byte                     " << hex << (int)media <<
  111.         "\n\tSerial number                     " << Shi << ':' << Slo <<
  112.         "\n\tVolume label                      " << setw(11) << label;
  113.     *ftype = save; cout <<
  114.         "\n\tFile system type                  " << setw(8) << ftype <<
  115.         "\n\n";
  116. }
  117.  
  118. void dpb::erase()
  119. {
  120.     (void *)FAT = new char[sperf*bpers];
  121.     absread(driveno, sperf, 1L, FAT);               // Read a FAT
  122.     for (int i = 2; i < ndata; i++)  zapentry(i);   // Kill real data clusters
  123.     if(abswrite(driveno, sperf , 1L, FAT)) {        // Write FATs out
  124.         cout << "Cannot write on disk " << (char)('A'+driveno) << endl;
  125.         return;
  126.     }
  127.     abswrite(driveno, sperf , 1L + sperf, FAT);
  128.     delete FAT;
  129.     char *buf = (char *)calloc(bpers, 1);           // Data for directory zap
  130.     for (i = 0; i < ndir/16; i++)
  131.         abswrite(driveno, 1, sdir + i, buf);    // Zap directory
  132.     free(buf);
  133. }
  134.  
  135. unsigned dpb::sector(unsigned cluster)      // Convert cluster # to sector #
  136. {
  137.     return ((cluster-2)<<shift) + data;
  138. }
  139.  
  140. unsigned dpb::getentry(unsigned c)          // Get FAT entry for cluster
  141. {
  142.     if (is16bit) return FAT[c];    /* 16 bit FAT entry */
  143.     unsigned index = (3*c)>>1;
  144.     WORD word = *(WORD *)((char)FAT+index);
  145.     unsigned result = (c&1? word>>4: word&0xfff);
  146.     if (result >= 0xff0) result |= 0xf000;
  147.     return result;
  148. }
  149.  
  150. void dpb::zapentry(unsigned c)              // Zap cluster if not bad
  151. {
  152.     if (is16bit) {if (FAT[c] != 0xfff7) FAT[c] = 0; return;} // Zap if not bad
  153.     unsigned index = (3*c)>>1;
  154.     WORD oldword = *(WORD *)((char *)FAT+index);
  155.     if (!(c&1)) oldword &= 0x0fff; else oldword >>= 4; // Position the entry
  156.     if (!oldword || oldword == 0xff7) return;          // If free or bad, return
  157.     *(WORD *)((char *)FAT+index) &= ((c&1)? 0x000f: 0xf000);    // Zap it
  158. }
  159.  
  160. void main(int, char *argv[])
  161. {
  162.     dpb *disk = new dpb(*argv[1]);
  163.     disk->list();
  164.     for (;;) {
  165.         if (disk->driveno > 1) cout << "This is a hard disk!!!\a" << endl;
  166.         cout << "Do you really want to zap this disk (Y/N)? " << flush;
  167.         char k; cin >> k; k = tolower(k);
  168.         if (k == 'n') return;
  169.         if (k == 'y') break;
  170.     }
  171.     disk->erase();
  172.     char buf[10];
  173.     sprintf(buf, "chkdsk %c:", 'a' + disk->driveno);
  174.     system(buf);
  175. }
  176.  
  177.